%==========================================================================
%=  This file is part of the Sound Restoration Project
%=  (c) Copyright Industrial Mathematics Institute
%=                University of South Carolina, Department of Mathematics
%=  ALL RIGHTS RESERVED
%=
%=  Author: Borislav Karaivanov
%==========================================================================

%==========================================================================
% List of the files on which this procedure depends:
%
% none
%
%==========================================================================

%==========================================================================
% The function "findMinRelativeDifference" takes two 2D arrays of the same
% height, computes the relative difference between their overlapping
% portions for a number of specified amounts of overlap (to be understood
% as horizontal overlap, i.e., along the width), and finds the smallest of
% those relative average absolute differences.
% REMARK: Below and elsewhere, for the sake of brevity, the relative
% average absolute difference will be called relative difference. It is
% important to use relative differences because otherwise a difference
% could be small just because two very low (in magnitude) portions of the
% signals are compared (there all samples have values close to zero and
% therefore the differences of the sample values can not be large). When
% relative differences are used we divide the usual difference by the sum
% of the L_1 norms of the two compared portions. Thus if the two portions
% are very low in magnitude we will be dividing by a small number and the
% relative difference will end up being larger as we would like it to be.
% INPUT: "firstArr" and "secondArr" are 2D arrays of the same height whose
% relative differences are to be computed. All overlaps are meant in the
% sense that the right end of the first signal overlaps the left end of the
% second signal.
% "minOverlap" and "maxOverlap" are positive integers specifying a range of
% overlaps for which relative differences are to be computed.
% OUTPUT: "bestOverlap" returns the overlap for which the smallest relative
% difference is attained.
% "minRelDiff" returns the smallest relative difference found.
%==========================================================================
function [bestOverlap, minRelDiff] = findMinRelativeDifference(firstArr, ...
    secondArr, minOverlap, maxOverlap)

% Allocate memory for the average absolute differences and sums
% corresponding to all overlaps in vicinity of the overlap guess.
aveDiffArr = zeros(maxOverlap - minOverlap + 1, 1);
aveSumArr = zeros(size(aveDiffArr));

% Compute the average absolute differences and sums for the specified
% amounts of overlap.
currInd = 1;
for k = minOverlap:maxOverlap
    
    aveDiffArr(currInd) = mean(mean(abs(firstArr(:, (end - k + 1):end) - secondArr(:, 1:k))));
    aveSumArr(currInd) = mean(mean(abs(firstArr(:, (end - k + 1):end)) + abs(secondArr(:, 1:k))));
    
    % Increment the index.
    currInd = currInd + 1;
end

% Compute the relative differences. 
relDiffArr = aveDiffArr./aveSumArr;

% Find the smallest among the computed relative differences.
[minRelDiff, minRelDiffInd] = min(relDiffArr);

% Compute the best-matching overlap.
bestOverlap = minOverlap + minRelDiffInd - 1;

return;
% end of the function "findMinRelativeDifference"
